package ctl
import ("github.com/unrolled/render"
	"net/http"
	"www2/sp"
	"gopkg.in/mgo.v2/bson"
	"html/template"
	"www2/util"
	"www2/sp/cats"
	"time"
	//"go/doc"
	//"log"
	//"go/doc"
	"strings"
	"www2/cfg"
	"log"
	"fmt"
)

const(
	CHEAD_LM="Last-Modified"
	CHEAD_CT="Content-Type"
)

func ResHandle(w http.ResponseWriter, r *http.Request) {
	t:=time.Now().Add(2400*time.Hour)
	w.Header().Add("Expires", t.Format(time.RFC1123))

	imgurl:=r.URL.String()[1:]
	img:=&sp.SImg{}
	err:=sp.SImgBongo.FindOne(bson.M{"furl":imgurl},img)
	if(err!=nil){
		if *cfg.DownloadMissRes{
			sp.DownLoadImgWithCheck(imgurl)
		}
		Rer.Text(w,404,err.Error()+imgurl)
		return
	}
	if r.Header.Get("If-Modified-Since")!="" && r.Header.Get("If-Modified-Since")==img.LM{
		w.WriteHeader(304)
		return
	}

	w.Header().Add(CHEAD_LM,img.LM)
	w.Header().Add(CHEAD_CT,img.CT)
	w.Write(img.Content)
	return
}

func IndexHandler(w http.ResponseWriter, r *http.Request) {
	subdomain:=util.GetSubDomainName(r);

	if subdomain!="" && subdomain!="www"{
		ContentHandler(w,r)
		return
	}
	urls:=[]string{
		"https://www.elastic.co/guide/en/elasticsearch/reference/current/index.html",
		"https://www.elastic.co/guide/en/elasticsearch/reference/2.2/index.html",
		"https://www.elastic.co/guide/en/elasticsearch/reference/2.1/index.html",
		"https://developer.mozilla.org/zh-CN/docs/Web/",
		"https://developer.mozilla.org/en-US/docs/Web/",
		"https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference",
		"https://developer.mozilla.org/zh-CN/docs/Web/CSS/Reference",
		"https://developer.mozilla.org/zh-CN/docs/Web/HTML/Reference",
		"http://redis.io/commands/",
		cats.GetRsWebSpider().Url,
		cats.Getw3WebSpider().Url,

	}

	docs:=[]sp.Doc{}
	err:= sp.DocMgo.Find(bson.M{"furl":bson.M{"$in":urls}}).Select(bson.M{"furl":1,"title":1}).All(&docs)
	if err==nil{
		//durl:=[]string{}
		for idx,doc:=range docs{
			for k,d:=range sp.DomainMap{
				if strings.HasPrefix(doc.FUrl,d){
					docs[idx].FUrl="//"+k+"."+*cfg.Domian+strings.TrimPrefix(doc.FUrl,d)
				}
			}

		}
		//log.Println(len(docs),docs)
		Rer.HTML(w,200,"index",docs)
		return
	}
	Rer.Text(w,500,err.Error())

}

func FlyHandler(w http.ResponseWriter, r *http.Request) {
	subDomain:=util.GetSubDomainName(r)

	if subDomain=="res"{
		ResHandle(w,r)
		return
	}

	//vars:=mux.Vars(r)
	//path:=vars["path"]
	//url:=sp.DomainMap[subDomain]+"/"+path
	url:=sp.DomainMap[subDomain]+strings.TrimPrefix( sp.UrlPathAndQuery(r.URL),"/fly")
	log.Println(subDomain,url,r.URL.Path)

	doc:=&sp.Shtml{}
	err:= sp.ShtmlBongo.FindOne(bson.M{"furl":url},doc)
	//log.Println(doc.CT,doc.LM,url)
	if(err==nil){
		//time.FixedZone("GMT", 0)
		//t:=time.Now().Add(240*time.Hour)
		//w.Header().Add("Expires", t.Format(time.RFC1123)) //   t.Format("Mon, 02 Jan 2006 15:04:05 "+"GMT")
		//
		//if r.Header.Get("If-Modified-Since")!="" && r.Header.Get("If-Modified-Since")==doc.LM{
		//	w.WriteHeader(304)
		//	return
		//}

		//w.Header().Add(CHEAD_LM,doc.LM)
		//w.Header().Add(CHEAD_CT,"text/html; charset=utf-8")

		doct:=&sp.Doc{}
		fc:=&sp.Spider{}
		if subDomain==sp.CD_mdn{
			fc=cats.GetMdnWebSpider()
		}
		if subDomain==sp.CD_es{
			fc=cats.GetEsWebSpider()
		}
		if subDomain==sp.CD_redis{
			fc=cats.GetRsWebSpider()
		}
		if subDomain==sp.CD_w3{
			fc=cats.Getw3WebSpider()
		}
		doct,err:=cats.ToDocDest(url,fc)

		if !strings.HasPrefix( doc.CT,"text/html")||r.Header.Get("X-Requested-With")!=""||
		strings.HasSuffix(r.URL.Path,"tryit.asp"){
			util.Log("render content without template",url)
			w.Header().Add(CHEAD_LM,doc.LM)
			w.Header().Add(CHEAD_CT,doc.CT)
			w.Write([]byte(doct.Content))
			return
		}


		if(err==nil){
			Rer.HTML(w,200,subDomain, doct)
			return
		}

	}
	if err!=nil{
		Rer.Text(w,500, fmt.Sprint(err, url,"FlyHandler"))
		return
	}

	//	w.Write([]byte(bs))

	//	w.Write([]byte("Gorilla!\n"+r.URL.Path+" "+r.Host+" string "+r.URL.String()))
}


func ContentHandler(w http.ResponseWriter, r *http.Request) {
	subDomain:=util.GetSubDomainName(r)

	if subDomain=="res"{
		ResHandle(w,r)
		return
	}
	//vars:=mux.Vars(r)
	//path:=vars["path"]
	//url:=sp.DomainMap[subDomain]+"/"+path

	url:=sp.DomainMap[subDomain]+sp.UrlPathAndQuery(r.URL)
	//log.Println(subDomain,url,r.URL.Path)
	tdoc:=&sp.Doc{}
	err:= sp.DocBongo.FindOne(bson.M{"furl":url},tdoc)

	if err!=nil {
		if err.Error()!="Document not found"{
			Rer.Text(w,500, fmt.Sprint(err, url,"ContentHandler"))
			return
		}else{

			fc:=&sp.Spider{}
			if subDomain==sp.CD_mdn{
				fc=cats.GetMdnWebSpider()
			}
			if subDomain==sp.CD_es{
				fc=cats.GetEsWebSpider()
			}
			if subDomain==sp.CD_redis{
				fc=cats.GetRsWebSpider()
			}
			if subDomain==sp.CD_w3{
				fc=cats.Getw3WebSpider()
			}
			tdoc,err=cats.ToDocDest(url,fc)
			if err!=nil {
				Rer.Text(w,500, fmt.Sprint(err, url,"convert  in ContentHandler"))
				return
			}

			err=sp.DocBongo.Save(tdoc)
			if err==nil{
				log.Println("convert doc:",tdoc.FUrl)

			}

			if err!=nil{
				Rer.Text(w,500, fmt.Sprint(err, url,"save  at ContentHandler"))
				return
			}
		}

	}

	//log.Println(doc.CT,doc.LM,url)

	//time.FixedZone("GMT", 0)
	t:=time.Now().Add(240*time.Hour)
	w.Header().Add("Expires", t.Format(time.RFC1123)) //   t.Format("Mon, 02 Jan 2006 15:04:05 "+"GMT")

	if r.Header.Get("If-Modified-Since")!="" && r.Header.Get("If-Modified-Since")==tdoc.LM{
		w.WriteHeader(304)
		return
	}

	if !strings.HasPrefix( tdoc.CT,"text/html")||
	r.Header.Get("X-Requested-With")!=""||
	strings.HasSuffix(r.URL.Path,"tryit.asp"){   //w3school
		util.Log("render content without template",url)
		w.Header().Add(CHEAD_LM,tdoc.LM)
		w.Header().Add(CHEAD_CT,tdoc.CT)
		w.Write([]byte(tdoc.Content))
		return
	}

	w.Header().Add(CHEAD_LM,tdoc.LM)
	w.Header().Add(CHEAD_CT,"text/html; charset=utf-8")


	if(err==nil){
		Rer.HTML(w,200,subDomain, tdoc)
		return
	}

	if err!=nil{
		Rer.Text(w,500, fmt.Sprint(err, url,"ContentHandler"))
		return
	}

//	w.Write([]byte(bs))

	//	w.Write([]byte("Gorilla!\n"+r.URL.Path+" "+r.Host+" string "+r.URL.String()))
}
var Rer *render.Render
func init(){
	Rer = render.New(render.Options{
		Directory: "templates",
		Asset: nil,
		AssetNames: nil,
		Layout: "",
		Extensions: []string{".tmpl"},

		Funcs: []template.FuncMap{
				{
					"str2html": func(raw string) template.HTML {
						return template.HTML(raw)
					},
				},
		},
		Delims: render.Delims{"{{", "}}"},
		Charset: "UTF-8",
		IndentJSON: false,
		IndentXML: false,
		PrefixJSON: []byte(""),
		PrefixXML: []byte(""),
		HTMLContentType: "text/html",
		IsDevelopment: false,
		UnEscapeHTML: false,
		StreamingJSON: false,
		RequirePartials: false,
		DisableHTTPErrorRendering: false,
	})
}


func RawHandler(w http.ResponseWriter, r *http.Request) {
	subDomain:=util.GetSubDomainName(r)

	//vars:=mux.Vars(r)
	//path:=vars["path"]
	//url:=sp.DomainMap[subDomain]+"/"+path
	url:=sp.DomainMap[subDomain]+strings.TrimPrefix( sp.UrlPathAndQuery(r.URL),"/raw")
	doc:=&sp.Shtml{}
	err:= sp.ShtmlBongo.FindOne(bson.M{"furl":url},doc)

	if err!=nil{
		Rer.Text(w,500, fmt.Sprint(err, url,"RawHandler"))
		return
	}
	w.Write([]byte(doc.Content))
}
